/*
 *     This file is part of Mobile GPS Logger.
 *
 *     Mobile GPS Logger is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Mobile GPS Logger is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License v3 for more details.
 *
 *     You should have received a copy of the GNU General Public License v3
 *     along with Mobile GPS Logger. If not, see <http://www.gnu.org/licenses/>.
 */

package cx.ath.skyflyer.gpslog.nmea;

import cx.ath.skyflyer.gpslog.util.Tokenizer;
import java.util.NoSuchElementException;

/**
 * An object of this class represents a GPGGA sentence.
 * @author Ahti Legonkov
 */
public class GpsFixData extends NmeaSentence {

    public static final String PREFIX = "$GPGGA";

    public static final int NO_FIX = 0;

    /**
     *
     * @param gpgaa an NMEA 0183 GPGGA sencence.
     * @throws java.util.NoSuchElementException if the given sentence does not
     *  contain enough tokens to compose GPGGA sencence.
     * @throws cx.ath.skyflyer.gpslog.UnsupportedTypeException if the sentence
     *  anything but GPGGA.
     */
    public GpsFixData(String gpgga)
            throws NoSuchElementException
            , UnsupportedTypeException
            , ChecksumMismatchException
    {
        super(gpgga);
        parser = new Tokenizer(gpgga);

        String type = parser.next();
        if (!type.equals(GpsFixData.PREFIX))
            throw new UnsupportedTypeException(GpsFixData.PREFIX, type);

        parse();
    }

    /**
     *
     * @return a string representation of altitude together with altitude unit.
     */
    public double getAltitude() throws NoSuchElementException {
        return m_Altitude;
    }

    public String getAltitudeUnit() throws NoSuchElementException {
        return m_AltitudeUnit;
    }

    public int getFixQuality() throws NoSuchElementException {
        return m_FixQuality;
    }

    public double getLatitude() throws NoSuchElementException {
        return m_Latitude;
    }

    public double getLongitude() throws NoSuchElementException {
        return m_Longitude;
    }

    public int getNumberOfSatellites() throws NoSuchElementException {
        return m_NumberOfSatellites;
    }

    /// Returns number of seconds
    public Time getTime() throws NoSuchElementException, NumberFormatException {
        return m_Time;
    }

    private void parse() throws NoSuchElementException {

        m_Time = new Time(parser.next());
        m_Latitude = NmeaUtils.degreesToRadians(parser.next());
        if (!parser.next().equals("N"))
            m_Latitude = -m_Latitude;

        m_Longitude = NmeaUtils.degreesToRadians(parser.next());
        if (!parser.next().equals("E"))
            m_Longitude = -m_Longitude;

        m_FixQuality = Integer.parseInt(parser.next());
        m_NumberOfSatellites = Integer.parseInt(parser.next());
        parser.next();
        m_Altitude = Double.parseDouble(parser.next());
        m_AltitudeUnit = parser.next();

        parser = null;
    }

    private Tokenizer parser;

    // $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75

    //Time  	170834  	17:08:34 UTC
    private Time m_Time;

    //Latitude 	4124.8963, N 	41d 24.8963' N or 41d 24' 54" N
    private double m_Latitude;

    //Longitude 	08151.6838, W 	81d 51.6838' W or 81d 51' 41" W
    private double m_Longitude;

    //Fix Quality:
    // 0 = Invalid
    // 1 = GPS fix
    // 2 = DGPS fix 	1 	Data is from a GPS fix
    private int m_FixQuality;

    //Number of Satellites 	05 	5 Satellites are in view
    private int m_NumberOfSatellites;

    //Horizontal Dilution of Precision (HDOP) 	1.5 	Relative accuracy of horizontal position
    //private String m_HorizontalDilutionOfPrecision;

    //Altitude 	280.2, M 	280.2 meters above mean sea level
    private double m_Altitude;
    private String m_AltitudeUnit;

    //Height of geoid above WGS84 ellipsoid 	-34.0, M 	-34.0 meters
    //Time since last DGPS update 	blank 	No last update
    //DGPS reference station id 	blank 	No station id
    //Checksum 	*75 	Used by program to check for transmission errors}
}
